﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ZRFCore.MotionControlCard;
using ZRFCore.Tool;
using System.IO;
using 喷点胶机;

namespace MultiAxisAssembly.Motion
{
    public class MachinePro : Machine
    {
        public double ZSafePos { get; set; }//Z轴安全高度位
        //private bool isRunMark = false;
        string calibPath = Directory.GetCurrentDirectory() + "/Calib/";
        /// <summary>
        /// 空移速度
        /// </summary>
        public float EmptyMoveSpeed = 500;

        /// <summary>
        /// 初始化完成
        /// </summary>
        public new bool IsInitialized { get { return isInitialized; } }
        private bool isInitialized = false;

        public MachinePro()
        {
            isInitialized = false;
            ZSafePos = 0;
        }

        public new void Init()
        {
            try
            {
                base.Init();
                base.In_EmergentStopButton.DisableEvent += In_EmergentStopButton_DisableEvent1;
                In_EmergentStopButton_DisableEvent1(null, null);//立即扫描一次急停事件看是否按下急停
                isInitialized = true;
            }
            catch (Exception)
            {
                throw;
            }
        }

        //急停输入断开事件处理器，触发设备急停
        private void In_EmergentStopButton_DisableEvent1(IInput? sender, InputEventArgs? e)
        {
            if (In_EmergentStopButton.Enable == false)
            {
                EmergentStop();
            }
        }

        public new void EmergentStop()
        {
            Out_SpurtGlueControl.Enable = false;
            Out_PointGlueControl.Enable = false;
            isAllHomed = false;
            base.EmergentStop();
        }

        public new void ResetEmergentStop()
        {
            if (In_EmergentStopButton.Enable == false)
            {
                throw new Exception("未解除急停按钮！");
            }

            base.ResetEmergentStop();
        }

        public new void Close()
        {
            EmergentStop();
            base.Close();
        }

        /// <summary>
        /// 去拍照位
        /// </summary>
        /// <param name="XSnapPos"></param>
        /// <param name="YSnapPos"></param>
        /// <param name="ZSnapPos"></param>
        public void GotoSnapPos()
        {
            AxisesLocation axisesLocation = XmlHelper.XmlDeserializeFromFile<AxisesLocation>(calibPath + "SnapPos.xml", Encoding.UTF8);
            int delayTime;
            if (this.XAxis.DPos == axisesLocation.XPos && this.YAxis.DPos == axisesLocation.YPos)
            {
                delayTime = 5;
            }
            else
            {
                delayTime = 1500;
            }
            InterpolationMove((float)axisesLocation.XPos, (float)axisesLocation.YPos, (float)axisesLocation.ZPos, base.MaxSpeed);
            Thread.Sleep(delayTime);
        }

        /// <summary>
        /// 三轴移动到指定位置，（Z轴低于安全高度自动上下）
        /// </summary>
        /// <param name="xPos"></param>
        /// <param name="yPos"></param>
        /// <param name="zPos"></param>
        /// <param name="speed"></param>
        /// <exception cref="Exception"></exception>
        public void InterpolationMove(float xPos, float yPos, float zPos, float speed)
        {
            if (this.MotionStatus.IsEmergentStop == true)
            {
                isRunMark = false;
                throw new Exception("急停中");
            }
            if (isRunMark == true)
            {
                throw new Exception("设备正在运转");
            }
            if (isAllHomed == false)
            {
                throw new Exception("请先复位！");
            }

            isRunMark = true;

            base.Speed = speed;//胶头平移速度
            base.Accel = speed * 5;
            base.Decel = speed * 5;
            if (Math.Abs(this.ZAxis.DPos) > Math.Abs(ZSafePos))//判断当前Z轴高度是否低于安全高度
            {
                this.ZAxis.MoveAbs((float)ZSafePos);
                this.ZAxis.WaitMoveStop();
            }
            List<double[]> snapPosList = new List<double[]>();
            snapPosList.Add(new double[] { xPos, yPos, 0 });
            snapPosList.Add(new double[] { xPos, yPos, zPos });
            this.Interpolation.MoveAbs(snapPosList);
            this.Interpolation.WaitMoveAbsOver();
            isRunMark = false;
        }

        /// <summary>
        /// 执行点胶动作
        /// </summary>
        /// <param name="machPath"></param>
        /// <param name="needOutGlue"></param>
        public void DoMachCoordPath(MachCoord2dPath machPath, bool needOutGlue = true)
        {
            if (this.MotionStatus.IsEmergentStop == true)
            {
                isRunMark = false;
                throw new Exception("急停中");
            }
            if (isRunMark == true)
            {
                throw new Exception("设备正在运转");
            }
            if (isAllHomed == false)
            {
                throw new Exception("请先复位！");
            }
            if (machPath.Shield == true)
            {
                return;
            }
            isRunMark = true;
            base.Interpolation.Speed = EmptyMoveSpeed;//胶头平移速度
            base.Interpolation.Accel = EmptyMoveSpeed * 5;
            base.Interpolation.Decel = EmptyMoveSpeed * 5;

            switch (machPath.Type)
            {
                case PathType.None:
                    break;
                case PathType.Glue:
                    Out_GlueChangeToSpurt.Enable = false;
                    Out_GlueChangeToSmall.Enable = true;
                    break;
                case PathType.SpurtGlue:
                    Out_GlueChangeToSpurt.Enable = true;
                    Out_GlueChangeToSmall.Enable = false;
                    break;
                case PathType.AvoidPath:
                    Out_GlueChangeToSpurt.Enable = false;
                    Out_GlueChangeToSmall.Enable = false;
                    break;
                default:
                    break;
            }

            //base.UnInterpolationCalcAxises = null;//new int[] { 3 };
            List<double[]> moveToEnterPointPoses = new List<double[]>();
            if (Math.Abs(base.ZAxis.DPos) > Math.Abs(ZSafePos))//判断当前Z轴高度是否低于安全高度
            {
                moveToEnterPointPoses.Add(new double[] { XAxis.DPos, YAxis.DPos, (float)ZSafePos });
            }
            moveToEnterPointPoses.Add(new double[] { machPath.XPoses[0], machPath.YPoses[0], ZAxis.DPos });//移动到点胶进入点上方安全位置
            moveToEnterPointPoses.Add(new double[] { machPath.XPoses[0], machPath.YPoses[0], machPath.ZPoses[0] });//移动到点胶第一个点
            base.Interpolation.MoveAbs(moveToEnterPointPoses);//执行点胶前移动
            base.Interpolation.WaitMoveAbsOver();//等待运行延时结束
            if (base.MotionStatus.IsEmergentStop == true)
            {
                isRunMark = false;
                return;
            }
            Thread.Sleep((int)(machPath.Delay_DelayToOutGlue * 1000));//到位延时时间
            //开始走点胶路径
            if (needOutGlue)
            {
                switch (machPath.Type)
                {
                    case PathType.None:
                        break;
                    case PathType.Glue:
                        base.Out_SpurtGlueControl.Enable = false;
                        base.Out_PointGlueControl.Enable = true;//打开点胶阀
                        break;
                    case PathType.SpurtGlue:
                        base.Out_PointGlueControl.Enable = false;
                        base.Out_SpurtGlueControl.Enable = true;//打开喷胶阀
                        break;
                    case PathType.AvoidPath:
                        base.Out_PointGlueControl.Enable = false;
                        base.Out_SpurtGlueControl.Enable = false;
                        break;
                    default:
                        break;
                }
            }
            if (base.MotionStatus.IsEmergentStop == true)
            {
                isRunMark = false;
                return;
            }
            Thread.Sleep((int)(machPath.Delay_OutGlueToStartMove * 1000));
            if (machPath.Speed == 0)
            {
                base.Interpolation.Speed = 1;//点胶插补速度
                base.Interpolation.Accel = 1 * 5;
                base.Interpolation.Decel = 1 * 5;
            }
            else
            {
                base.Interpolation.Speed = (int)machPath.Speed;//点胶插补速度
                base.Interpolation.Accel = (int)machPath.Speed * 5;
                base.Interpolation.Decel = (int)machPath.Speed * 5;
            }
            //base.UnInterpolationCalcAxises = new int[] { 3 };//R轴不参与插补计算
            List<double[]> moveAbs = new List<double[]>();
            for (int i = 1; i < machPath.XPoses.Length; i++)
            {
                moveAbs.Add(new double[] { machPath.XPoses[i], machPath.YPoses[i], machPath.ZPoses[i] });
            }
            base.Interpolation.MoveAbs(moveAbs);
            base.Interpolation.WaitMoveAbsOver();
            switch (machPath.Type)
            {
                case PathType.None:
                    break;
                case PathType.Glue:
                    base.Out_PointGlueControl.Enable = false;//关点胶阀
                    break;
                case PathType.SpurtGlue:
                    base.Out_SpurtGlueControl.Enable = false;//关喷胶阀
                    break;
                case PathType.AvoidPath:
                    break;
                default:
                    break;
            }
            //base.UnInterpolationCalcAxises = null;//new int[] { 3 };//R轴参与插补计算
            //List<double[]> moveEnd = new List<double[]>();//点胶插补收尾
            //moveEnd.Add(new double[] { machPath.LastPointX, machPath.LastPointY, ZWorkPos - 5, base.RPos });
            //base.MoveAbs(moveEnd);//执行收尾插补
            //base.WaitMoveAbsOver();
            Thread.Sleep((int)(machPath.Delay_StopGlueDelayTime * 1000));
            //点胶结束出去
            base.Interpolation.Speed = EmptyMoveSpeed;//胶头平移速度
            base.Interpolation.Accel = EmptyMoveSpeed * 5;
            base.Interpolation.Decel = EmptyMoveSpeed * 5;
            base.ZAxis.MoveAbs((float)ZSafePos);//抬高Z轴
            base.ZAxis.WaitMoveStop();
            isRunMark = false;
        }

    }
}
